// cf-494c
// 题意：现在有n(<=10^5)个人，每个人初始有个ai单位钱，然后现在有q(<=5000)段区间，
//       区间之间要么不相交，要么完全包含。然后告诉你每段区间接受的概率，
//       如果被接受这这段区间内所有人的钱+1, 然后所有区间都算完后，
//       钱数最多人的钱作为goodness值，现在要求这个值的期望。
//
// 题解：用期望公式很难推出来，所以要用定义式。
//       我们定义mx[i]表示第i段线段初始最大值为mx[i]，然后用
//       f[i][j]表示第i段线段在结束所有区间计算后价值不超过mx[i]+j的概率，
//       然后最后答案就可以用f[i][j]来计算。
//
//       要维护f[i][j]用O(q^2)的树形dp就能转移出来。
//       
// run: $exec < input
// opt: 0
// flag: -g
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>

struct data
{
	int l, r;
	double p;
};

std::vector<data> da;

int const maxn = 100007;
int const maxq = 5007;
int head[maxq], end[2 * maxq], next[2 * maxq];
int alloc = 2;
int a[maxn];
int max[maxq];
double pa[maxq][maxq];
int n, q;

void add_edge(int u, int v)
{
	end[alloc] = v; next[alloc] = head[u]; head[u] = alloc++;
}

int tree[maxn];

int lowbit(int x) { return x & -x; }

void update(int id, int v)
{
	for (; id <= n; id += lowbit(id)) tree[id] = std::max(tree[id], v);
}

int query(int l, int r)
{
	int ret = a[r];
	for (; ; ) {
		ret = std::max(ret, a[r]);
		if (r == l) break;
		for (r--; r - l >= lowbit(r); r -= lowbit(r))
			ret = std::max(ret, tree[r]);
	}
	return ret;
}

void dfs(int u, int parent)
{
	for (int p = head[u]; p; p = next[p]) {
		int v = end[p];
		if (v == parent) continue;
		dfs(v, u);
	}
	for (int j = 0; j <= q; j++) {
		double p1 = da[u].p, p2 = (1 - da[u].p);
		for (int p = head[u]; p; p = next[p]) {
			int v = end[p];
			if (v == parent) continue;
			int t = std::min(q, max[u] - max[v] + j - 1);
			if (t >= 0) p1 *= pa[v][t];

			t = std::min(q, max[u] - max[v] + j);
			p2 *= pa[v][t];
		}
		if (!j) pa[u][j] = p2;
		else pa[u][j] = p1 + p2;
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> q;
	for (int i = 1; i <= n; i++) {
		std::cin >> a[i];
		update(i, a[i]);
	}
	da.resize(q + 1);
	da[0].l = 1; da[0].r = n; da[0].p = 0;
	for (int i = 1; i <= q; i++)
		std::cin >> da[i].l >> da[i].r >> da[i].p;
	std::sort(da.begin(), da.end(), [](data const & a, data const & b) {
				return a.l < b.l || (a.l == b.l && a.r > b.r);
			});
	for (int i = 0; i <= q; i++)
		max[i] = query(da[i].l, da[i].r);
	for (int i = 1; i <= q; i++)
		for (int j = i - 1; j >= 0; j--)
			if (da[j].l <= da[i].l && da[i].r <= da[j].r) {
				add_edge(j, i);
				break;
			}
	dfs(0, -1);

	double ans = pa[0][0] * max[0];
	for (int i = 1; i <= q; i++)
		ans += (pa[0][i] - pa[0][i - 1]) * (max[0] + i);
	std::cout << std::fixed << std::setprecision(9) << ans << '\n';
}

